; Teste estático de PolishCalc
; Por: Italo Valcy <italo@dcc.ufba.br>
; Licença: GNU General Public License

%include 'macros.i'

extern   _write
extern   _exit
extern   _strlen
extern   _strcmp
extern   _IntToAsc
extern   _FpuToAsc
extern   Syntactic
extern   PolishCalc

section .data


; table with data input. Sintaxe: <expr to calc>,0
InputTable     db       0
               db       '3+2',0     ; test 01
               db       '5*3 + 8/(7:5)',0    ; test 02
               db       '1,63 * (12,5 - 9,539)*(2,7+0,45)',0   ; test 03
               db       '(12,37 + 4,628) * 2,5 ** -3',0        ; test 04
               db       '(7,342-9,5710) * (-12,13+14,087)/(-2,2**0,5)',0   ; test 05
               db       '(5 < 6,43 AND 1 > 0) * (5,14+2-1,17)**-3',0       ; test 06
               db       '((2,34 - 5,2 * 0,34) ** (5,7 - 3,7)) / (-4,62 + 4,62)',0   ; test 07
               db       '((1 < 0) OR (1 > 0)) AND ((3 = 2) XOR (7 <= 9))',0   ; test 08
               db       '((1 OR 2 AND 3) + (1 AND 2 XOR 3)) OR (1 >= 0)',0    ; test 09
               db       '1+2+3',0   ; test 10
               db       '3**4',0    ; test 11

SizeInputTable equ      $-InputTable



; table with expected output. Each line must have a byte with the
; return code, sixteen chars with the expected value and the caracter
; '\0' (== ascii(0))
ExpectedTable  db       000,'          5,0000',0   ; test 01
               db       000,'         19,0000',0   ; test 02
               db       000,'         15,2033',0   ; test 03
               db       000,'          1,0879',0   ; test 04
               db       004,'                ',0   ; test 05
               db       000,'          0,0047',0   ; test 06
               db       002,'                ',0   ; test 07
               db       000,'          1,0000',0   ; test 08
               db       001,'                ',0   ; test 09
               db       000,'          6,0000',0   ; test 10
               db       000,'         81,0000',0   ; test 11



msgFail        db       10,10,'Failure computing expression: ',10
sizeMsgFail    equ      $-msgFail

msgRCFail      db       10,'<rC = '
rCExpected     db       '    '
msg2RCFail     db       '> expected, but was',10,'<rC = '
rCFound        db       '    '
msg3RCFail     db       '>'
sizeMsgRCFail  equ      $-msgRCFail

msg1ValueFail  db       10,'<'
sizeMsg1ValueFail equ   $-msg1ValueFail
msg2ValueFail  db       '> expected, but was',10,'<'
sizeMsg2ValueFail equ   $-msg2ValueFail
msg3ValueFail  db       '>'
sizeMsg3ValueFail equ   $-msg3ValueFail

msgFinishTest  db       10,10,'Tests = '
numTests       times    9 db 0
msg2FinishTest db       10,'Assertions =  '
numAssertions  times    9 db 0
msg3FinishTest db       10,'Failures = '
numFailures    times    9 db 0
msg4FinishTest db       10
sizeMsgFinish  equ      $-msgFinishTest

tests          dd       0
assertions     dd       0
failures       dd       0

section .bss
rC       resd     1
polonesa resb     512
tamExpr  resd     1
polVal   resq     1
ascVal   resb     17

section .text
   global _start

_start:
   mov   esi, InputTable
   mov   edi, ExpectedTable
   mov   ecx, 1
   jmp   .TestNextExpression

.ShortFinishTest:
   jmp   .FinishTest
.ShortVerifyRC:
   jmp   .VerifyRC
   
.TestNextExpression:
   cmp   ecx, SizeInputTable
   jnb   .ShortFinishTest
   inc   dword [tests]

   call  _executeProgram
   cmp   dword [rC], 0
   jne   .ShortVerifyRC

   mov   byte [ascVal], ' '
   xcall _FpuToAsc,_,polVal,ascVal,16,_,4
   mov   byte [ascVal+16], 0
   inc   edi
   xcall _strcmp,edi,ascVal
   cmp   eax, 0
   jne   .ShortInvalidValue
   inc   dword [assertions]

.ContinueTestExpression:
   add   ecx, dword [tamExpr]
   inc   ecx
   add   esi, dword [tamExpr]
   add   edi, 17    ; next line of expectedTable
   jmp   .TestNextExpression

.ShortInvalidValue:
   jmp   .InvalidValue

.VerifyRC:
   movzx edx, byte [edi]
   inc   edi
   cmp   dword [rC], edx
   jne   .InvalidRC

   inc   dword [assertions]
   jmp   .ContinueTestExpression

.InvalidRC:
   xcall _IntToAsc,edx,rCExpected,4
   xcall _IntToAsc,dword [rC],rCFound,4
   
   xcall _write,_,msgFail,sizeMsgFail
   xcall _write,_,esi,dword [tamExpr]
   xcall _write,_,msgRCFail,sizeMsgRCFail

   inc   dword [failures]
   jmp   .ContinueTestExpression

.InvalidValue:
   xcall _write,_,msgFail,sizeMsgFail
   xcall _write,_,esi,dword [tamExpr]
   xcall _write,_,msg1ValueFail,sizeMsg1ValueFail
   xcall _write,_,edi,16
   xcall _write,_,msg2ValueFail,sizeMsg2ValueFail
   xcall _write,_,ascVal,16
   xcall _write,_,msg3ValueFail,sizeMsg3ValueFail
   inc   dword [failures]
   jmp   .ContinueTestExpression

.FinishTest:
   xcall _IntToAsc,dword [tests],numTests,9
   xcall _IntToAsc,dword [assertions],numAssertions,9
   xcall _IntToAsc,dword [failures],numFailures,9

   xcall _write,_,msgFinishTest,sizeMsgFinish
   xcall _exit

_executeProgram:
   xcall Syntactic,esi,polonesa,rC
   inc   esi
   xcall _strlen,esi
   mov   dword [tamExpr], eax
   xcall PolishCalc,polonesa,polVal,rC
   ret
